﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Caca.MineSweeper.AI
{
    class ConditionFactory
    {
        internal static Condition Build(int x, int y, Plot p)
        {
            Condition result = null;
            if (p is NonMinePlot)
            {
                var nmp = p as NonMinePlot;

                Location f = new Location() { X = x, Y = y };
                HashSet<Location> fields = new HashSet<Location>();
                fields.Add(f);
                result = new OpenedField(f, nmp.SurroundMines);
            }
            else if (p is MinePlot)
            {
                throw new NotImplementedException();
            }
            return result;
        }

        internal static Condition Build(IEnumerable<Location> fields, int mines)
        {
            return new MinesInFields(fields, mines);
        }

        internal static Condition Build(Location field, bool isMine)
        {
            return new SingleField(field, isMine);
        }
    }

    internal class Condition
    {
        protected Condition()
        {
            Fields = new HashSet<Location>();
        }

        public int Mines { get; protected set; }
        public HashSet<Location> Fields { get; protected set; }
        public double AveragePossibility { get { return (double)Mines / (double)Fields.Count; } }
    }

    /// <summary>
    /// 代表已经在游戏中打开的非地雷格子
    /// </summary>
    internal class OpenedField : Condition
    {
        //public OpenedField(Location field) : this(field, 0) { }

        internal OpenedField(Location field, int surroundMines)
            : base()
        {
            this.Mines = 0;
            this.SurroundMines = surroundMines;
            this.Field = field;
            this.Fields.Add(field);
        }

        /// <summary>
        /// 该格子周围的地雷数目
        /// </summary>
        public int SurroundMines { get; private set; }

        public Location Field { get; private set; }
    }

    /// <summary>
    /// 表示若干格子中存在若干地雷, 每个格子是地雷的概率都一样
    /// </summary>
    internal class MinesInFields : Condition
    {
        public MinesInFields(IEnumerable<Location> fields, int mines)
            : base()
        {
            this.Mines = mines;
            this.Fields = new HashSet<Location>(fields);
        }
    }

    /// <summary>
    /// 代表单个格子, 该格子已经推断出一定是或者一定不是地雷
    /// </summary>
    internal class SingleField : Condition
    {
        public SingleField(Location field, bool isMine) : base()
        {
            this.Field = field;
            this.IsMine = isMine;
            this.Fields.Add(field);
            this.Mines = IsMine ? 1 : 0;
        }

        public Location Field { get; private set; }
        public bool IsMine { get; private set; }

    }
}
